﻿using JKFrame;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEditor.PackageManager;
using UnityEngine;

public partial class ClientsManager : SingletonMono<ClientsManager>
{

    public void InitLoginSystem()
    {
        NetMessageManager.Instance.RegisterMessageCallback(MessageType.C_S_EnterGame, OnClientEnterGame);
        //NetMessageManager.Instance.RegisterMessageCallback(MessageType.C_S_Disonnect, OnClientDisonnect);

        
    }


    private Dictionary<ClientState, HashSet<Client>> clientStateDic;
    // Key:clientID
    private Dictionary<ulong, Client> clientIDDic;
    // Key:账号 Value:ClientID
    private Dictionary<string, ulong> accountDic;
    public void Init()
    {
        clientStateDic = new Dictionary<ClientState, HashSet<Client>>()
        {
            { ClientState.Connected,new HashSet<Client>(100)},
            { ClientState.Logined,new HashSet<Client>(100)},
            { ClientState.Gaming,new HashSet<Client>(100)},
        };
        clientIDDic = new Dictionary<ulong, Client>(100);
        accountDic = new Dictionary<string, ulong>(100);
        NetManager.Instance.OnClientConnectedCallback += OnClientConnected;
        NetManager.Instance.OnClientDisconnectCallback += OnClientNetCodeDisconnect;
        InitLoginSystem();
        //InitChatSystem();
        //InitItemSystem();
    }

    private void SetClientState(ulong clientID, ClientState newState)
    {
        if (clientIDDic.TryGetValue(clientID, out Client client))
        {
            clientStateDic[client.clientState].Remove(client);
            clientStateDic[newState].Add(client);
            client.clientState = newState;
        }
    }

    // 连接成功
    private void OnClientConnected(ulong clientID)
    {
        Client client = ResSystem.GetOrNew<Client>();
        client.clientID = clientID;
        clientIDDic.Add(clientID, client);
        SetClientState(clientID, ClientState.Connected);
    }

    public void AddClient(ulong clientID,ClientState clientState)
    {
        Client client = ResSystem.GetOrNew<Client>();
        client.clientID = clientID;
        client.playerData = ResSystem.GetOrNew<PlayerData>();
        client.playerData.characterData.position = MapManager.Instance.GetFirstBirthPos();
        clientIDDic.Add(clientID, client);
        SetClientState(clientID, clientState);
    }


    // 客户端完全退出
    private void OnClientNetCodeDisconnect(ulong clientID)
    {
        if (clientIDDic.Remove(clientID, out Client client))
        {
            clientStateDic[client.clientState].Remove(client);
            //if (client.playerData != null) accountDic.Remove(client.playerData.name);
            // 目前采用的是Netcode自己的管理，也就是客户端掉线会自动清除所述网络对象
            if (client.playerController != null) NetManager.Instance.DestroyObject(client.playerController.mainController.NetworkObject);
            //client.playerData = null;
            client.playerController = null;
            client.OnDestroy();
        }
    }


    // 玩家进入游戏  主机端直接创建角色
    private void OnClientEnterGame(ulong clientID, INetworkSerializable serializable)
    {
        // 无需回复客户端，直接创建角色
        Client client = clientIDDic[clientID];
        if (client.clientState == ClientState.Gaming) return;
        SetClientState(clientID, ClientState.Gaming);
        PlayerData playerData = client.playerData;
        CharacterData characterData = playerData.characterData;
        NetworkObject playerObject = NetManager.Instance.SpawnObjectNoShow(clientID, ServerResSystem.serverConfig.playerPrefab, characterData.position, Quaternion.Euler(0, characterData.rotation_Y, 0));
        // 初始化玩家的服务端控制脚本
        if (!playerObject.TryGetComponent(out PlayerController serverController))
        {
            serverController = playerObject.gameObject.AddComponent<PlayerController>();
            //serverController.FirstInit(playerObject.GetComponent<PlayerController>());
            serverController.FirstInit();
        }
        serverController.Init();
        playerObject.SpawnWithOwnership(clientID);
        playerObject.NetworkShow(clientID);
        //serverController.mainController.playerName.Value = playerData.name;
        //serverController.mainController.usedWeaponName.Value = playerData.characterData.usedWeaponName;
        //serverController.mainController.currentHp.Value = playerData.characterData.hp;
        client.player = serverController;
    }


    public void CreatePlayer(ulong clientID)
    {
        // 无需回复客户端，直接创建角色
        Client client = clientIDDic[clientID];
        PlayerData playerData = client.playerData;
        CharacterData characterData = playerData.characterData;

        NetworkObject playerObject = NetManager.Instance.SpawnObject(clientID, ServerResSystem.serverConfig.playerPrefab, characterData.position, Quaternion.Euler(0, characterData.rotation_Y, 0));
        // 初始化玩家的服务端控制脚本
        if (!playerObject.TryGetComponent(out PlayerController serverController))
        {
            serverController = playerObject.gameObject.AddComponent<PlayerController>();
            //serverController.FirstInit(playerObject.GetComponent<PlayerController>());
            serverController.FirstInit();
        }
        serverController.Init();
        playerObject.SpawnWithOwnership(clientID);
        playerObject.NetworkShow(clientID);
        //serverController.mainController.playerName.Value = playerData.name;
        //serverController.mainController.usedWeaponName.Value = playerData.characterData.usedWeaponName;
        //serverController.mainController.currentHp.Value = playerData.characterData.hp;
        client.player = serverController;
    }

}
